#include "../include/httpConnection.h"
#include <iostream>
#include "../include/LogicHandler.h"
httpConnection::httpConnection(boost::asio::io_context &_io_context):_socket(_io_context){
	
}



void httpConnection::start_read(){

    auto self=shared_from_this();
    http::async_read(_socket,_buffer,_request,[self](boost::beast::error_code ec, std::size_t){
        if(ec){
            std::cout<<"收包出错："<<ec.what()<<std::endl;
			//这个存在问题，下面的remote_endpoint是系统调用，is_open是_socket内部维护的一个标志，可能is_open为true，但是系统层面已经断开，所以抛异常
			// if(self->_socket.is_open()){
			// 	std::cout<<"马上关闭的连接："<<self->_socket.remote_endpoint().address()<<" "<<self->_socket.remote_endpoint().port()<<std::endl;
			// }
            return;
        }
        self->handle_request(self); //去处理完成的包
        self->start_read(); 
		//继续读取，这是为了让客户端去关闭连接，不要让服务器出现大量time_wait状态
		//这样还能保证async_write的时候，self还在，毕竟只有对端收到包，关闭连接，这个才会真正销毁
    });
}

void httpConnection::handle_request(const std::shared_ptr<httpConnection>&con)
{
    //要根据方法，去执行
    //auto self=shared_from_this();     //不需要了,通过捕获的con,直接往下传递就好了
    if(_request.method()==http::verb::get){
        LogicHandler::get_instance()->handler_get(con);
        
        return;
    }
    if(_request.method()==http::verb::post){
        LogicHandler::get_instance()->handler_post(con);
		
        return;
    }

    
}

httpConnection::~httpConnection(){
	std::cout<<"成功释放一个连接"<<std::endl;
    
}

void httpConnection::response_404()
{
    //这里返回404  not found----最好封装一下
    //设置基础
    this->_response.version(_request.version());
    this->_response.result(http::status::not_found);
    this->_response.keep_alive(false);
    //设置响应头
    this->_response.set(http::field::content_type,"text/plain");
    
    boost::beast::ostream(this->_response.body())<<"not found";
    this->_response.prepare_payload();    //自动计算大小，并填入头部
    auto self=shared_from_this();
    http::async_write(this->_socket,this->_response,[self](boost::beast::error_code, ::std::size_t){
        std::cout<<"成功发送一个 404 响应"<<std::endl;
    });

}




//编解码url,获取查询参数
unsigned char ToHex(unsigned char x)
{
	return  x > 9 ? x + 55 : x + 48;
}

unsigned char FromHex(unsigned char x)
{
	unsigned char y;
	if (x >= 'A' && x <= 'Z') y = x - 'A' + 10;
	else if (x >= 'a' && x <= 'z') y = x - 'a' + 10;
	else if (x >= '0' && x <= '9') y = x - '0';
	else assert(0);
	return y;
}

//编码
std::string UrlEncode(const std::string& str)
{
	std::string strTemp = "";
	size_t length = str.length();
	for (size_t i = 0; i < length; i++)
	{
		//判断是否仅有数字和字母构成
		if (isalnum((unsigned char)str[i]) ||
			(str[i] == '-') ||
			(str[i] == '_') ||
			(str[i] == '.') ||
			(str[i] == '~'))
			strTemp += str[i];
		else if (str[i] == ' ') //为空字符
			strTemp += "+";
		else
		{
			//其他字符需要提前加%并且高四位和低四位分别转为16进制
			strTemp += '%';
			strTemp += ToHex((unsigned char)str[i] >> 4);
			strTemp += ToHex((unsigned char)str[i] & 0x0F);
		}
	}
	return strTemp;
}

//解码
std::string UrlDecode(const std::string& str)
{
	std::string strTemp = "";
	size_t length = str.length();
	for (size_t i = 0; i < length; i++)
	{
		//还原+为空
		if (str[i] == '+') strTemp += ' ';
		//遇到%将后面的两个字符从16进制转为char再拼接
		else if (str[i] == '%')
		{
			assert(i + 2 < length);
			unsigned char high = FromHex((unsigned char)str[++i]);
			unsigned char low = FromHex((unsigned char)str[++i]);
			strTemp += high * 16 + low;
		}
		else strTemp += str[i];
	}
	return strTemp;
}

void httpConnection::prase_get_url(){
    // 提取 URI  
	auto uri = _request.target();
	// 查找查询字符串的开始位置（即 '?' 的位置）  
	auto query_pos = uri.find('?');
	if (query_pos == std::string::npos) {
		_get_url = uri;
		return;
	}

	_get_url = uri.substr(0, query_pos);
	std::string query_string = uri.substr(query_pos + 1);
	std::string key;
	std::string value;
	size_t pos = 0;
	while ((pos = query_string.find('&')) != std::string::npos) {
		auto pair = query_string.substr(0, pos);
		size_t eq_pos = pair.find('=');
		if (eq_pos != std::string::npos) {
			key = UrlDecode(pair.substr(0, eq_pos)); // 假设有 url_decode 函数来处理URL解码  
			value = UrlDecode(pair.substr(eq_pos + 1));
			url_key_value[key] = value;
		}
		query_string.erase(0, pos + 1);
	}
	// 处理最后一个参数对（如果没有 & 分隔符）  
	if (!query_string.empty()) {
		size_t eq_pos = query_string.find('=');
		if (eq_pos != std::string::npos) {
			key = UrlDecode(query_string.substr(0, eq_pos));
			value = UrlDecode(query_string.substr(eq_pos + 1));
			url_key_value[key] = value;
		}
	}
}